package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.storage.domain.*;
import com.pureut.storage.dto.*;
import com.pureut.storage.mapper.*;
import com.pureut.storage.service.*;
import com.pureut.storage.util.UnitUtil;
import com.pureut.storage.utils.DocumentTypeEnum;
import com.pureut.storage.utils.GenerationMethodEnum;
import com.pureut.storage.utils.MaxNumberUtils;
import com.pureut.storage.vo.*;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.domain.R;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.dict.utils.DictUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.goods.api.RemoteGoodsIncomeService;
import com.sale.goods.api.dto.ImparityGoodsDto;
import com.sale.goods.api.vo.GetDataByCodeGoodsVo;
import com.sale.order.api.RemoteCustomerService;
import com.sale.order.api.RemoteSaleService;
import com.sale.order.api.vo.BackDataVo;
import com.sale.order.api.vo.SaleServiceVo;
import com.sale.storage.api.vo.InvoiceVo;
import com.sale.system.api.*;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.SysUser;
import com.sale.system.api.domain.dto.SysDocumentResultDto;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import com.sale.system.api.domain.vo.SysWorkbenchAuditAgentDubboVo;
import com.sale.system.api.model.MaterialUnitDto;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.swing.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.extension.toolkit.Db.getById;
import static com.baomidou.mybatisplus.extension.toolkit.Db.updateById;

/**
 * 销售发货实现层
 *
 * @author: CM
 * @date: 2023/7/17  11:31
 */
@Service
@RequiredArgsConstructor
public class PickingSaleServiceImpl extends ServiceImpl<PickingSaleMapper, PickingSale> implements PickingSaleService {

    /**
     * 编码生成配置
     */
    @DubboReference
    private final RemoteCodeService remoteCodeService;

    /**
     * 销售订单mapper
     */
    private final PickingSaleMapper pickingSaleMapper;

    /***
     * 销售订单明细mapper
     *
     */
    private final PickingSaleDetailMapper pickingSaleDetailMapper;

    /**
     * 销售订单Service
     */
    private final PickingSaleDetailService pickingSaleDetailService;

    /**
     * 审核服务调用
     */
    @DubboReference
    private final RemoteReviewService remoteReviewService;

    /**
     * 仓库mapper
     */
    private final WmsStockInfoMapper wmsStockInfoMapper;

    /**
     * 仓库建模mapper
     */
    private final WarehouseMapper warehouseMapper;

    /**
     * 采购退货Mapper
     */
    private final PickingPurchaseMapper pickingPurchaseMapper;

    /**
     * 远程调用菜单管理
     */
    @DubboReference
    RemoteMenuService remoteMenuService;

    /**
     * 远程调用单据配置
     */
    @DubboReference
    RemoteDocumentService remoteDocumentService;

    /**
     * 单位Mapper
     */
    @DubboReference
    RemoteUnitService remoteUnitService;


    /**
     * 拣货方案
     */
    private final PickingSchemeService pickingSchemeService;

    /**
     * 用户信息
     */
    @DubboReference
    RemoteUserService remoteUserService;

    /**
     * 销售订单
     */
    @DubboReference
    RemoteSaleService remoteSaleService;


    @DubboReference
    RemoteSysCustomerService remoteCustomerService;

    @DubboReference
    RemoteGoodsIncomeService remoteGoodsIncomeService;

    //销售退货
    private final SalesReturnMapper salesReturnMapper;

    //采购入库
    private final PurchaseReceiptMapper purchaseReceiptMapper;

    @DubboReference
    RemoteWorkbenchMessageService remoteWorkbenchMessageService;

    @Resource
    PublicMaterialMapper publicMaterialMapper;

    /**
     * 日志Mapper
     */
    private final OutboundLogMapper outboundLogMapper;


    /**
     * 日志Mapper
     */
    private final OutboundLogService outboundLogService;

    @Resource
    UnitUtil unitUtil;

    @Resource
    BarCodePrintingService barCodePrintingService;

    @Resource
    BarCodePrintingMapper barCodePrintingMapper;

    @Resource
    WmsStockInfoService wmsStockInfoService;

    /**
     * 新增销售发货
     *
     * @param pickingSaleVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSale(PickingSaleVo pickingSaleVo) throws Exception {
        List<PickingSaleRelationVo> list = pickingSaleVo.getList();

        List<PickingSale> pickingSalelist = new ArrayList<>();
        if (list.size() > 0) {

            for (PickingSaleRelationVo pickingSaleRelationVo : list) {

                String sn = remoteCodeService.authorityCoding("warehouse:outbound:shipsale:list");
                if (sn == null || "".equals(sn)) {
                    throw new GlobalException("该单据未进行配置,无法生成单据编码");
                }

                PickingSale pickingSale = new PickingSale();
                BeanUtils.copyProperties(pickingSaleVo, pickingSale);
                BeanUtils.copyProperties(pickingSaleRelationVo, pickingSale);
                pickingSale.setCreateUser(LoginHelper.getUsername())
                    .setOutOfStock(pickingSaleRelationVo.getOutOfStock())
                    .setDrawerTime(new Date())
                    .setCreateTime(new Date())
                    .setDocumentType(DocumentTypeEnum.PICKING_SALE.getCode())
                    .setWodDocNum(sn)
                    .setMaterialUnit(pickingSaleRelationVo.getMaterialUnit())
                    .setDeptId(LoginHelper.getDeptId())
                    .setWodStatus(1)
                    .setConnectionId(pickingSaleRelationVo.getConnectionId())
                    .setMaterialUnit(pickingSaleRelationVo.getMaterialUnit())
                    .setMaterialCode(pickingSaleRelationVo.getMaterialCode())
                    .setCustomerNum(pickingSaleVo.getCustomerNum())
                    .setUnitPrice(pickingSaleRelationVo.getUnitPrice())
                    .setGenerationMode(GenerationMethodEnum.MANUALLY_GENERATED.getCode());
                pickingSalelist.add(pickingSale);
            }
            return pickingSaleMapper.insertBatch(pickingSalelist);
        } else {
            throw new GlobalException("请至少添加一条物料明细");
        }
    }

    /**
     * 新增销售发货（销售订单使用）
     *
     * @param pickingSaleVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSaleOrder(PickingSaleVo pickingSaleVo) throws Exception {
        List<PickingSaleRelationVo> list = pickingSaleVo.getList();

        List<PickingSale> pickingSalelist = new ArrayList<>();
        if (list.size() > 0) {

            for (PickingSaleRelationVo pickingSaleRelationVo : list) {

                String sn = remoteCodeService.authorityCoding("warehouse:outbound:shipsale:list");
                if (sn == null || "".equals(sn)) {
                    throw new GlobalException("该单据未进行配置,无法生成单据编码");
                }

                PickingSale pickingSale = new PickingSale();
                BeanUtils.copyProperties(pickingSaleVo, pickingSale);
                BeanUtils.copyProperties(pickingSaleRelationVo, pickingSale);
                pickingSale.setCreateUser(LoginHelper.getUsername())
                    .setOutOfStock(pickingSaleRelationVo.getOutOfStock())
                    .setDrawerTime(new Date())
                    .setCreateTime(new Date())
                    .setDocumentType(DocumentTypeEnum.PICKING_SALE.getCode())
                    .setWodDocNum(sn)
                    .setMaterialUnit(pickingSaleRelationVo.getMaterialUnit())
                    .setDeptId(LoginHelper.getDeptId())
                    .setWodStatus(1)
                    .setConnectionId(pickingSaleRelationVo.getConnectionId())
                    .setMaterialUnit(pickingSaleRelationVo.getMaterialUnit())
                    .setMaterialCode(pickingSaleRelationVo.getMaterialCode())
                    .setCustomerNum(pickingSaleVo.getCustomerNum())
                    .setConnectionId(pickingSaleRelationVo.getConnectionId())
                    .setUnitPrice(pickingSaleRelationVo.getUnitPrice())
                    .setGenerationMode(GenerationMethodEnum.AUTO_GENERATE.getCode());
                pickingSalelist.add(pickingSale);
            }
            return pickingSaleMapper.insertBatch(pickingSalelist);
        } else {
            throw new GlobalException("请至少添加一条物料明细");
        }
    }

    /**
     * 财务-核销单 通过获取未全部核销的销售发货单、销售退货单、其他收入单数据
     */
    @Override
    public TableDataInfo<ImparityDto> getNoVerificationList(GetDataByCodeVo getDataByCodeVo, PageQuery pageQuery) {
        //销售发货单
        List<ImparityDto> pickingSaleVerification = pickingSaleMapper.getNoVerification(getDataByCodeVo);
        //销售退货单
        List<ImparityDto> salesReturnVerification = salesReturnMapper.getNoVerification(getDataByCodeVo);
        //其他收入单
        GetDataByCodeGoodsVo getDataByCodeGoodsVo = new GetDataByCodeGoodsVo();
        getDataByCodeGoodsVo.setClientCode(getDataByCodeVo.getClientCode());
        getDataByCodeGoodsVo.setCreateTime(getDataByCodeVo.getCreateTime());
        getDataByCodeGoodsVo.setReceiptNumber(getDataByCodeVo.getReceiptNumber());
        List<ImparityGoodsDto> noVerificationList = remoteGoodsIncomeService.getNoVerificationList(getDataByCodeGoodsVo);
        List<ImparityDto> resultList = new ArrayList<>();
        for (ImparityGoodsDto entity : noVerificationList) {
            ImparityDto imparityDto = new ImparityDto();
            BeanUtils.copyProperties(entity, imparityDto);
            resultList.add(imparityDto);
        }

        resultList.addAll(pickingSaleVerification);
        resultList.addAll(salesReturnVerification);
        //手动分页
        Page<ImparityDto> page = new Page<>();
        List<ImparityDto> collect = resultList.stream().skip((long) (pageQuery.getPageNum() - 1) * pageQuery.getPageSize()).limit(pageQuery.getPageSize()).collect(Collectors.toList());
        page.setRecords(collect);
        page.setTotal(resultList.size());
        return TableDataInfo.build(page);
    }

    /**
     * 销售发货修改
     *
     * @param pickingSaleVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSale(PickingSaleVo pickingSaleVo) {
        //查询当前id对应的单据
        PickingSale pickingSale = pickingSaleMapper.selectById(pickingSaleVo.getId());
        int wodStatus = pickingSale.getWodStatus();
        if (wodStatus != 1 && wodStatus != 4) {
            throw new GlobalException("只能对“待提交”,“未通过”状态的单据进行修改");
        }
        if (pickingSale.getGenerationMode() == 1) {
            throw new GlobalException("自动生成的单据不能修改");
        }

        if (wodStatus == 4) {

            //调用审核
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            String perms = "warehouse:outbound:shipsale:examine";
            String auditDoc = pickingSale.getWodDocNum();
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setPerms(perms);
            int i = remoteReviewService.editHistory(sysAuditHistoryVo);
            if (i > 0) {
                pickingSale.setWodStatus(1);

                //修改审核代办状态为已处理
                remoteWorkbenchMessageService.updateStatus(3, pickingSale.getWodDocNum(), "销售发货");//
            }
        }

        List<PickingSaleRelationVo> list = pickingSaleVo.getList();
        PickingSaleRelationVo pickingSaleRelationVo = list.get(0);

        pickingSale.setTransceiverType(pickingSaleVo.getTransceiverType());
        pickingSale.setCustomerNum(pickingSaleVo.getCustomerNum());
        pickingSale.setDateDelivery(pickingSaleVo.getDateDelivery());
        pickingSale.setRemark(pickingSaleVo.getRemark());
        pickingSale.setDrawerTime(pickingSaleVo.getDrawerTime());

        pickingSale.setPlannedWeight(pickingSaleRelationVo.getPlannedWeight());
        pickingSale.setOutOfStock(pickingSaleRelationVo.getOutOfStock());
        pickingSale.setMaterialUnit(pickingSaleRelationVo.getMaterialUnit());

        return updateById(pickingSale);
    }

    /**
     * 关结单据
     *
     * @param pickingSaleVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean closeSale(PickingSaleVo pickingSaleVo) {
        //查询当前单据的状态，只能对待提交，未通过，待审核，审核中，待出库，待交接，状态的单据进行关结
        PickingSale pickingSale = pickingSaleMapper.selectById(pickingSaleVo.getId());
        //取出当前的单据状态
        int wodStatus = pickingSale.getWodStatus();

        if (wodStatus != 1 && wodStatus != 2 && wodStatus != 3 && wodStatus != 4 && wodStatus != 5 && wodStatus != 10) {
            throw new GlobalException("只能对状态为“待提交、未通过、待审核、审核中、待出库、待交接”状态的单据进行关结");
        }

        //根据单号获取销售发货单明细
        List<PickingSaleDetail> pickingSaleDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

        List<WmsStockInfo> wmsStockInfos = new ArrayList<>();
        //拆包要修改的库存集合
        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

        for (PickingSaleDetail pickingSaleDetail : pickingSaleDetailList) {
            //如果是拆包的
            if ("1".equals(pickingSaleDetail.getIsPackage())){
                //查询库存扣减数量，如果扣完数量为0则删掉库存
                String materialNumber = pickingSaleDetail.getPdoductNumber();
                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                BigDecimal bigDecimal = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                BigDecimal bigDecimal1 = new BigDecimal(pickingSaleDetail.getOutgoingNumber());
                BigDecimal subtract = bigDecimal.subtract(bigDecimal1);
                boolean flag = subtract.compareTo(BigDecimal.ZERO)==0;
                if (flag){
                    wmsStockInfos.add(chaiWmsStock);
                }else{
                    chaiWmsStock.setWsiMaterialStatus(2);
                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                    updateList.add(chaiWmsStock);
                }
            }else {
                WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, pickingSaleDetail.getPdoductNumber()));
                if (wmsStockInfos != null) {
                    wmsStockInfos.add(wmsStockInfo);
                }
            }
        }

        if (updateList.size()>0){
            wmsStockInfoService.updateBatchById(updateList);
        }

        if (wmsStockInfos.size() > 0) {
            wmsStockInfoMapper.deleteBatchIds(wmsStockInfos);

//            if (!b) {
//                throw new GlobalException("关结失败");
//            }
        }

        //取出关结人
        String closeMan = pickingSale.getCloseMan();
        if (closeMan != null) {
            closeMan = closeMan + "," + LoginHelper.getUsername();
        } else {
            closeMan = LoginHelper.getUsername();
        }
        //修改单据状态未关结，修改关结原因，修改关结人，修改关结时间
        PickingSale pickingSale1 = new PickingSale();
        pickingSale1.setId(pickingSaleVo.getId())
            .setWodStatus(8).setCloseTime(new Date())
            .setCloseMan(closeMan)
            .setCloseCause(pickingSaleVo.getCloseCause())
            .setCloseTime(new Date());
        return updateById(pickingSale1);

    }

    /**
     * 删除单据
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSale(String ids) {
        //将ids根据逗号拆分成数组
        List<String> idStr = Arrays.asList(ids.split(","));
        if (idStr.size() == 0) {
            throw new GlobalException("请至少勾选一条单据");
        }
        //根据ids批量查询出list列表
        List<PickingSale> pickingSales = pickingSaleMapper.selectBatchIds(idStr);

        //遍历
        for (PickingSale pickingSale : pickingSales) {
            if (pickingSale.getWodStatus() != 1 && pickingSale.getWodStatus() != 4) {
                throw new GlobalException("只能删除“待提交”或“未通过”状态的单据");
            } else if (pickingSale.getGenerationMode() != 2) {
                throw new GlobalException("系统自动生成的单据不可删除");
            }
        }

        for (PickingSale pickingSale : pickingSales) {
            remoteWorkbenchMessageService.deleteDoc(pickingSale.getWodDocNum(), "销售发货");
        }

        return pickingSaleMapper.deleteBatchIds(idStr) > 0;
    }


    /**
     * 提交审核
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitSale(String ids) {
        //将ids根据逗号拆分成数组
        List<String> idStr = Arrays.asList(ids.split(","));
        if (idStr.size() == 0) {
            throw new GlobalException("请至少勾选一条单据");
        }
        //根据ids批量查询出list列表
        List<PickingSale> pickingSales = pickingSaleMapper.selectBatchIds(idStr);

        //遍历
        for (PickingSale pickingSale : pickingSales) {
            if (pickingSale.getWodStatus() != 1) {
                throw new GlobalException("只能对状态为“待提交”的单据进行提交操作");
            }
            pickingSale.setWodStatus(2);


            SysWorkbenchAuditAgentDubboVo sysWorkbenchAuditAgentDubboVo = new SysWorkbenchAuditAgentDubboVo();
            sysWorkbenchAuditAgentDubboVo.setDocConfig("warehouse:outbound:shipsale:examine");
            sysWorkbenchAuditAgentDubboVo.setReceiptName("销售发货");
            sysWorkbenchAuditAgentDubboVo.setReceiptNumber(pickingSale.getWodDocNum());//
            sysWorkbenchAuditAgentDubboVo.setStatus(1);//待审核
            sysWorkbenchAuditAgentDubboVo.setReceiptContent("有单据待审核,请及时审核");

            remoteWorkbenchMessageService.insertAuditAgent(sysWorkbenchAuditAgentDubboVo);

        }
        return pickingSaleMapper.updateBatchById(pickingSales);
    }

    /**
     * 销售发货列表
     *
     * @param pickingSaleVo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<PickingSaleDto> getList(PickingSaleVo pickingSaleVo, PageQuery pageQuery) throws Exception {

        //查询销售发货列表
        Page<PickingSaleDto> pickingSaleList = pickingSaleMapper.getPickingSaleList(pageQuery.build(), pickingSaleVo);

        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();

        //获取单据状态字典数据
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "picking_sale_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //收发类型
        List<SysDictData> saleTypeArray = CacheUtils.get(CacheNames.SYS_DICT, "picking_sale_type");
        Map<String, String> saleTypeMap = saleTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //客户
        Map<String, String> supplierMap = remoteCustomerService.getOpenCustomerFinance();
        for (PickingSaleDto pickingSaleDto : pickingSaleList.getRecords()) {

            //收发类型
            pickingSaleDto.setTransceiverTypeDict(saleTypeMap.get(pickingSaleDto.getTransceiverType()));

            //类型
            if ("1".equals(pickingSaleDto.getCategory())) {
                pickingSaleDto.setMaterialCategoryDict("原料");
            } else {
                pickingSaleDto.setMaterialCategoryDict("成品");
            }
//            //客户信息
//            pickingSaleDto.setCustomNameDict(supplierMap.get(pickingSaleDto.getCustomerNum()));
            //查看仓库名称
            Warehouse warehouse = warehouseMapper.selectById(pickingSaleDto.getOutOfStock());
            if (warehouse != null) {
                //添加仓库名称
                pickingSaleDto.setOutOfStockDict(warehouse.getWarehouseName());
                pickingSaleDto.setOutOfStock(pickingSaleDto.getOutOfStock());
            }

            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + pickingSaleDto.getTenantId(), String.valueOf(pickingSaleDto.getMaterialId()));
            pickingSaleDto.setAuxiliaryAttribute(statsArray);

            //添加单据类型
            pickingSaleDto.setDocumentType(DocumentTypeEnum.getValue(Integer.parseInt(pickingSaleDto.getDocumentType())));

            //添加单据状态
            pickingSaleDto.setWodStatusDict(pickingSaleDto.getWodStatus() + "");
            pickingSaleDto.setWodStatus(statusMap.get(pickingSaleDto.getWodStatus() + ""));

            //添加生产方式
            pickingSaleDto.setGenerationMode(GenerationMethodEnum.getValue(Integer.parseInt(pickingSaleDto.getGenerationMode())));

            //添加单位key
            pickingSaleDto.setMaterialUnitDict(pickingSaleDto.getMaterialUnit() + "");

            //物料单位
            if (pickingSaleDto.getMaterialUnit() != null) {
                pickingSaleDto.setMaterialUnitDict(unitByCodeToMap.get(pickingSaleDto.getMaterialUnit()).getUnitName());
            }
//            //如果该物料配置了多单位，就进行单位转换
//            if (pickingSaleDto.getMaterialMoreUnit() != null) {
//                //转换
//                UnitConversionDto unitConversionDto = unitUtil.atWillunitConversion(pickingSaleDto.getMaterialUnit(), pickingSaleDto.getMaterialCode(),
//                    String.valueOf(pickingSaleDto.getPlannedWeight()), pickingSaleDto.getMaterialId());
//                if (unitConversionDto != null) {
//                    pickingSaleDto.setUnitConversion(unitConversionDto.getMaterialMoreUnitNumber());
//                }
//            }
            //单位转换
            String s = unitUtil.unitC(pickingSaleDto.getMaterialCode(),
                String.valueOf(pickingSaleDto.getPlannedWeight()),
                pickingSaleDto.getMaterialId(),
                unitByCodeToMap.get(String.valueOf(pickingSaleDto.getMaterialUnit())).getUnitName());
            pickingSaleDto.setUnitConversion(s);


//            String unitName = remoteUnitService.getUnitDataByCode(Long.valueOf(pickingSaleDto.getMaterialUnit())).getData().getUnitName();
//
//            //添加单位值
//            pickingSaleDto.setMaterialUnit(unitName);

        }
        return TableDataInfo.build(pickingSaleList);
    }

    /**
     * 审核单据
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saleReview(OrderReviewVo orderReviewVo) throws Exception {
        PickingSale pickingSale = pickingSaleMapper.selectById(orderReviewVo.getId());
        if (pickingSale.getWodStatus() == 2 || pickingSale.getWodStatus() == 3) {
            String perms = "warehouse:outbound:shipsale:examine";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = pickingSale.getWodDocNum();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = LoginHelper.getUserId();

            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            sysAuditHistoryVo.setPerms(perms);
            sysAuditHistoryVo.setAuditType(9);
            sysAuditHistoryVo.setAuditState(isAdopt);
            sysAuditHistoryVo.setAuditRemarks(auditRemarks);
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setUserId(userId);

            Integer data = remoteReviewService.getSequence(sysAuditHistoryVo);

            if (data == null) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                if (data == 1) {
                    pickingSale.setWodStatus(5);
                    if (pickingSale.getReviewBy() == null) {
                        pickingSale.setReviewBy(LoginHelper.getUsername());
                    } else {
                        pickingSale.setReviewBy(pickingSale.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    pickingSale.setReviewTime(new Date());

                    remoteWorkbenchMessageService.updateStatus(3, pickingSale.getWodDocNum(), "销售发货");

                    return updateById(pickingSale);
                } else if (data == 2) {
                    pickingSale.setWodStatus(3);
                    if (pickingSale.getReviewBy() == null) {
                        pickingSale.setReviewBy(LoginHelper.getUsername());
                    } else {
                        pickingSale.setReviewBy(pickingSale.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    pickingSale.setReviewTime(new Date());
                    return updateById(pickingSale);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    pickingSale.setWodStatus(4);
                    if (pickingSale.getReviewBy() == null) {
                        pickingSale.setReviewBy(LoginHelper.getUsername());
                    } else {
                        pickingSale.setReviewBy(pickingSale.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    pickingSale.setReviewTime(new Date());


                    SysWorkbenchAuditAgentDubboVo sysWorkbenchAuditAgentDubboVo = new SysWorkbenchAuditAgentDubboVo();
                    sysWorkbenchAuditAgentDubboVo.setDocConfig("warehouse:outbound:shipsale:examine");
                    sysWorkbenchAuditAgentDubboVo.setReceiptName("销售发货");
                    sysWorkbenchAuditAgentDubboVo.setReceiptNumber(pickingSale.getWodDocNum());//
                    sysWorkbenchAuditAgentDubboVo.setStatus(2);//待处理
                    sysWorkbenchAuditAgentDubboVo.setReceiptContent("有单据未通过,请及时查看");

                    sysWorkbenchAuditAgentDubboVo.setPassFlag("1");
                    sysWorkbenchAuditAgentDubboVo.setCreateName(pickingSale.getCreateUser());

                    remoteWorkbenchMessageService.insertAuditAgent(sysWorkbenchAuditAgentDubboVo);

                    return updateById(pickingSale);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("状态为待审核和审核中的单据才能进行审核");
        }

    }

    /**
     * 查看单据
     *
     * @param id
     * @return
     */
    @Override
    public PickingSaleDto view(Long id) {
        //查询单条对象
        PickingSaleDto pickingSaleDto = pickingSaleMapper.getPickingSaleById(id);

        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();

        //添加单据类型
        pickingSaleDto.setDocumentTypeDict(DocumentTypeEnum.getValue(Integer.parseInt(pickingSaleDto.getDocumentType())));
        pickingSaleDto.setDocumentType(pickingSaleDto.getDocumentType());

        List<PickingSaleViewDto> list = new ArrayList<>();

        PickingSaleViewDto pickingSaleViewDto = new PickingSaleViewDto();

        //查看仓库名称
        Warehouse warehouse = warehouseMapper.selectById(pickingSaleDto.getOutOfStock());
        if (warehouse != null) {
            //添加仓库名称
            pickingSaleViewDto.setOutOfStockDict(warehouse.getWarehouseName());
            pickingSaleViewDto.setOutOfStock(pickingSaleDto.getOutOfStock());
        }

        if (pickingSaleDto.getMaterialUnit() != null) {
            String unitName = remoteUnitService.getUnitDataByCode(Long.valueOf(pickingSaleDto.getMaterialUnit())).getData().getUnitName();

            //添加单位key
            pickingSaleViewDto.setMaterialUnitDict(unitName);
        }

        //辅助属性
        List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + pickingSaleDto.getTenantId(), String.valueOf(pickingSaleDto.getMaterialId()));
        pickingSaleViewDto.setAuxiliaryAttribute(statsArray);


        //添加单位值
        pickingSaleViewDto.setMaterialUnit(pickingSaleDto.getMaterialUnit());

        //添加物料名称，物料规格，物料料号
        pickingSaleViewDto.setMaterialCode(pickingSaleDto.getMaterialCode());
        pickingSaleViewDto.setMaterialName(pickingSaleDto.getItemName());
        pickingSaleViewDto.setMaterialSpec(pickingSaleDto.getItemSpec());

        //添加销售订单号
        pickingSaleViewDto.setConnectionId(pickingSaleDto.getConnectionId());
        //添加计划量
        pickingSaleViewDto.setPlannedWeight(pickingSaleDto.getPlannedWeight());

        if (pickingSaleDto.getMaterialUnit() != null) {
            //单位
            pickingSaleViewDto.setMaterialUnitDict(unitByCodeToMap.get(pickingSaleDto.getMaterialUnit()).getUnitName());
        }

        list.add(pickingSaleViewDto);
        pickingSaleDto.setList(list);

        return pickingSaleDto;
    }

    /**
     * 撤销审核
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean revoke(String ids) {

        String[] split = ids.split(",");

        List<String> list = Arrays.asList(split);

        List<PickingSale> pickingSales = pickingSaleMapper.selectList(new QueryWrapper<PickingSale>().lambda().in(PickingSale::getId, list));

        //2.保存成功后状态变为“待提交”
        for (PickingSale pickingSale : pickingSales) {
            //1.校验状态为“待审核”的单据才允许撤销审核
            if (2 != pickingSale.getWodStatus()) {
                throw new GlobalException("只有状态为“待审核”的单据才允许撤销审核");
            }
            //2.保存成功后状态变为“待提交”
            pickingSale.setWodStatus(1);
            remoteWorkbenchMessageService.deleteDoc(pickingSale.getWodDocNum(), "销售发货");
        }

        //3单据明细变为“待提交”状态
        return pickingSaleMapper.updateBatchById(pickingSales);
    }

    /**
     * 拣货方案
     *
     * @param id
     * @return
     */
    @Override
    public SchemeDto point(Long id) {
        PickingSale byId = pickingSaleMapper.selectById(id);
        SchemeVo schemeVo = new SchemeVo();
        schemeVo.setMaterialCode(byId.getMaterialCode());
        schemeVo.setAssociatedDetails("3");
        return pickingSchemeService.getSchemeData(schemeVo);
    }

    /**
     * 销售发货出库
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickingRestDbDto out(PickingRestDbVo pickingRestDbVo) {
        //出库类型
        String type = pickingRestDbVo.getType();
        //输入值
        String inputValue = pickingRestDbVo.getInputValue();

        PickingRestDbDto pickingRestDbDto = new PickingRestDbDto();

        //判断是否超收或者超发
        //获取菜单id
        Long menuId = remoteMenuService.getIdByMenuName("销售发货");
        SysDocumentResultDto sysDocument = remoteDocumentService.getInfoConfig(menuId);

        PickingSale byId = getById(pickingRestDbVo.getId());
        PublicMaterial publicMaterial = publicMaterialMapper.selectOne(new QueryWrapper<PublicMaterial>().lambda().eq(PublicMaterial::getMaterialCode, byId.getMaterialCode()));

        String unitName = remoteUnitService.getUnitDataByCode(publicMaterial.getMaterialUnit()).getData().getUnitName();

        //如果是扫码出库
        if ("1".equals(type)) {
            //判断扫描的物料条码是否一致
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, inputValue).eq(WmsStockInfo::getWsiMaterialStatus, 2));

            if (wmsStockInfo == null) {
                pickingRestDbDto.setCode("500");
                pickingRestDbDto.setMessage("扫描失败，请核实后扫描");
                return pickingRestDbDto;
            }

            if ("1".equals(wmsStockInfo.getWsiFreezeInfo())) {
                throw new GlobalException("此物料已冻结请重新输入");
            }

            //扫描的物料编码
            String wsiMaterialCode = wmsStockInfo.getWsiMaterialCode();
            //查询委外发货单中的物料编码、
            PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

            if (!pickingSale.getMaterialCode().equals(wsiMaterialCode)) {
                pickingRestDbDto.setMessage("500");
                pickingRestDbDto.setMessage("扫描失败，请核实后扫描");
                return pickingRestDbDto;
            }

            //判断是否重复扫描(在明细表中查询是否有该条码)
            PickingSaleDetail pickingSaleDetail1 = pickingSaleDetailMapper.selectOne(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getPdoductNumber, inputValue).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
            if (pickingSaleDetail1 != null) {
                pickingRestDbDto.setMessage("500");
                pickingRestDbDto.setMessage("请勿重复扫描");
                return pickingRestDbDto;
            }

            PickingSaleDetail pickingSaleDetail = new PickingSaleDetail();
            //物料号码
            pickingSaleDetail.setPdoductNumber(inputValue);

            //物料编码
            pickingSaleDetail.setItemCode(wmsStockInfo.getWsiMaterialCode());

            //物料状态
            pickingSaleDetail.setWodStatus(3);

            //关联单号
            pickingSaleDetail.setWodDocNum(pickingSale.getWodDocNum());

            //出库数量
            pickingSaleDetail.setOutgoingNumber(String.valueOf(wmsStockInfo.getWsiNetWeight()));

            //批次号
            pickingSaleDetail.setBatchNumber(wmsStockInfo.getWsiMaterialBatch());


            //厚度
            pickingSaleDetail.setThick(wmsStockInfo.getWsiThick());

            //幅宽
            pickingSaleDetail.setBreadth(wmsStockInfo.getWsiWidth());
            //卷长
            pickingSaleDetail.setRollLength(wmsStockInfo.getWsiLength());


            //仓储信息
            pickingSaleDetail.setWarehouseInfo(wmsStockInfo.getWsiWarehourseInfo());

            //出库人
            pickingSaleDetail.setDepositor(LoginHelper.getUsername());

            //出库时间
            pickingSaleDetail.setDeliveryTime(new Date());

            //判断是否有检验
            int docInspectionMark = sysDocument.getDocInspectionMark();
            //如果有检验
            if (docInspectionMark == 1) {
                //修改单据明细为待检验
                pickingSaleDetail.setWodStatus(1);
            } else {
                //判断是否有交接
                int docHandoverMark = sysDocument.getDocHandoverMark();
                //有交接
                if (docHandoverMark == 1) {
                    //修改单据明细为待交接
                    pickingSaleDetail.setWodStatus(2);

                }
            }
            //添加明细
            pickingSaleDetailMapper.insert(pickingSaleDetail);

            //修改委外发货单的单据状态为出库中
            pickingSale.setWodStatus(6);
            //修改出库重量和出库数量
            Double outgoingWeight = pickingSale.getOutgoingWeight();
            if (outgoingWeight == null) {
                outgoingWeight = 0.0;
            }
            BigDecimal bigDecimal = new BigDecimal(String.valueOf(outgoingWeight));
            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(wmsStockInfo.getWsiNetWeight()));

            BigDecimal add = bigDecimal.add(bigDecimal1);
            pickingSale.setOutgoingWeight(add.doubleValue());
            Integer outgoingNumber = pickingSale.getOutgoingNumber();
            if (outgoingNumber == null) {
                outgoingNumber = 0;
            }
            pickingSale.setOutgoingNumber(outgoingNumber + 1);


            //实际量
            pickingSale.setActualNumber(pickingSale.getOutgoingWeight());


            updateById(pickingSale);

            //修改仓库物料的状态为备料
            wmsStockInfo.setWsiMaterialStatus(5);
            int i = wmsStockInfoMapper.updateById(wmsStockInfo);


            //返回前端参数
            //计划/实际
            pickingRestDbDto.setQuantityIdentification(pickingSale.getPlannedWeight() + "/" + pickingSale.getActualNumber() + unitName);
            //出库数量
            pickingRestDbDto.setAllotNumOut(pickingSale.getOutgoingNumber() + "");

            pickingRestDbDto.setMessage("物料号码:" + inputValue + ",出库量:" + wmsStockInfo.getWsiNetWeight() + "出库成功");


            OutboundLog outboundLog = new OutboundLog();
            BeanUtils.copyProperties(wmsStockInfo, outboundLog, new String[]{"id"});
            outboundLog.setWodDocNum(pickingSale.getWodDocNum());
            boolean save = outboundLogService.save(outboundLog);


            //查询当前生产领料单
            PickingSale pickingSale1 = pickingSaleMapper.selectById(pickingRestDbVo.getId());
            //判断是否有超收
            int docHairMark = sysDocument.getDocHairMark();
            //没有超收
            if (docHairMark != 1) {
                //计划出库重量
                Double allotAmount = pickingSale1.getPlannedWeight();
                //实际出库重量
                Double allotWeightOut = pickingSale1.getActualNumber();
                if (allotWeightOut >= allotAmount) {

                    //判断是否有交接
                    int docHandoverMark = sysDocument.getDocHandoverMark();
                    //有交接
                    if (docHandoverMark == 1) {
                        //修改单据为待交接
                        pickingSale1.setWodStatus(10);
                        pickingSaleMapper.updateById(pickingSale1);

                    } else {
                        //修改单据为已完成
                        pickingSale1.setWodStatus(7);
                        //删除库存
                        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

                        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                        //拆包要修改的库存集合
                        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

                        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

                            if ("1".equals(stock.getIsPackage())) {
                                //如果是拆包的

                                //查询库存扣减数量，如果扣完数量为0则删掉库存
                                String materialNumber = stock.getPdoductNumber();
                                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                                BigDecimal subtract = wmsBig.subtract(outNumBig);
                                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                                if (flag) {
                                    deleteList.add(chaiWmsStock);
                                } else {
                                    chaiWmsStock.setWsiMaterialStatus(2);
                                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                                    updateList.add(chaiWmsStock);
                                }
                            } else {
                                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                                if (wmsStockInfo1 != null) {
                                    deleteList.add(wmsStockInfo1);
                                }
                            }
                        }
                        if (updateList.size() > 0) {
                            wmsStockInfoService.updateBatchById(updateList);
                        }

                        if (deleteList.size() > 0) {
                            wmsStockInfoMapper.deleteBatchIds(deleteList);
                        }

                        pickingSaleMapper.updateById(pickingSale1);
                    }
                }

            }
            //拣货方案
            SchemeDto point = point(pickingRestDbVo.getId());

            if (point.getCombinationName() != null) {
                pickingRestDbDto.setPickingPrompt(point.getCombinationName());
            }

            pickingRestDbDto.setCode("200");


        } else if ("2".equals(type)) {
            //批次出库
            //查询当前批次对应单条码信息
            List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, inputValue).eq(WmsStockInfo::getWsiMaterialStatus, 2).notIn(WmsStockInfo::getWsiFreezeInfo, 1));

            if (wmsStockInfoList.size() == 0) {
                pickingRestDbDto.setMessage("500");
                pickingRestDbDto.setMessage("扫描失败,此批次在库存中数量为0");
                return pickingRestDbDto;
            }

            //查询当前批次(在库的重量之和)
            Double netWeight = wmsStockInfoMapper.getNetWeight(inputValue);

            //查询委外出库单中的物料编码
            PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

            List<PickingSaleDetail> list = new ArrayList<PickingSaleDetail>();

            List<OutboundLog> outboundLogList = new ArrayList<OutboundLog>();

            for (WmsStockInfo wmsStockInfo : wmsStockInfoList) {


                //扫描的物料编码
                String wsiMaterialCode = wmsStockInfo.getWsiMaterialCode();

                if (!pickingSale.getMaterialCode().equals(wsiMaterialCode)) {
                    pickingRestDbDto.setCode("500");
                    pickingRestDbDto.setMessage("扫描失败，请核实后扫描");
                    return pickingRestDbDto;
                }


                //新增生产领料明细
                PickingSaleDetail pickingSaleDetail = new PickingSaleDetail();

                //物料编码
                pickingSaleDetail.setItemCode(pickingSale.getMaterialCode());

                //物料号码
                pickingSaleDetail.setPdoductNumber(wmsStockInfo.getWsiMaterialNumber());

                //物料状态
                pickingSaleDetail.setWodStatus(3);

                //关联单号
                pickingSaleDetail.setWodDocNum(pickingSale.getWodDocNum());

                //出库数量
                pickingSaleDetail.setOutgoingNumber(String.valueOf(wmsStockInfo.getWsiNetWeight()));

                //批次号
                pickingSaleDetail.setBatchNumber(wmsStockInfo.getWsiMaterialBatch());

                //克重
                pickingSaleDetail.setGramWeight(wmsStockInfo.getWsiGrawWeight());

                //厚度
                pickingSaleDetail.setThick(wmsStockInfo.getWsiThick());

                //幅宽
                pickingSaleDetail.setBreadth(wmsStockInfo.getWsiWidth());
                //卷长
                pickingSaleDetail.setRollLength(wmsStockInfo.getWsiLength());


                //仓储信息
                pickingSaleDetail.setWarehouseInfo(wmsStockInfo.getWsiWarehourseInfo());

                //出库人
                pickingSaleDetail.setDepositor(LoginHelper.getUsername());

                //出库时间
                pickingSaleDetail.setDeliveryTime(new Date());

                //判断是否有检验
                int docInspectionMark = sysDocument.getDocInspectionMark();
                //如果有检验
                if (docInspectionMark == 1) {
                    //修改单据明细为待检验
                    pickingSaleDetail.setWodStatus(1);
                } else {
                    //判断是否有交接
                    int docHandoverMark = sysDocument.getDocHandoverMark();
                    //有交接
                    if (docHandoverMark == 1) {
                        //修改单据明细为待交接
                        pickingSaleDetail.setWodStatus(2);
                    }
                }
                list.add(pickingSaleDetail);


                //修改出库重量和出库数量
                Double outgoingWeight = pickingSale.getOutgoingWeight();
                if (outgoingWeight == null) {
                    outgoingWeight = 0.0;
                }
                BigDecimal bigDecimal = new BigDecimal(String.valueOf(outgoingWeight));
                BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(wmsStockInfo.getWsiNetWeight()));

                BigDecimal add = bigDecimal.add(bigDecimal1);
                pickingSale.setOutgoingWeight(add.doubleValue());
                Integer outgoingNumber = pickingSale.getOutgoingNumber();
                if (outgoingNumber == null) {
                    outgoingNumber = 0;
                }

                pickingSale.setOutgoingNumber(outgoingNumber + 1);


                //修改仓库物料的状态为备料
                wmsStockInfo.setWsiMaterialStatus(5);

                OutboundLog outboundLog = new OutboundLog();
                BeanUtils.copyProperties(wmsStockInfo, outboundLog, new String[]{"id"});
                outboundLog.setWodDocNum(pickingSale.getWodDocNum());
                outboundLogList.add(outboundLog);

            }

            //添加明细
            pickingSaleDetailMapper.insertBatch(list);
            wmsStockInfoMapper.updateBatchById(wmsStockInfoList);

            //修改生产领料单的单据状态为出库中
            pickingSale.setWodStatus(6);

            //实际量
            pickingSale.setActualNumber(pickingSale.getOutgoingWeight());

            updateById(pickingSale);


            PickingSale pickingSale1 = pickingSaleMapper.selectById(pickingRestDbVo.getId());
            //返回前端参数
            //计划/实际
            pickingRestDbDto.setQuantityIdentification(pickingSale1.getPlannedWeight() + "/" + pickingSale1.getActualNumber() + unitName);
            //出库数量
            pickingRestDbDto.setAllotNumOut(pickingSale1.getOutgoingNumber() + "");


            pickingRestDbDto.setMessage("批次号:" + inputValue + ",出库量:" + netWeight + ",数量:" + wmsStockInfoList.size() + "出库成功");


            boolean save = outboundLogService.saveBatch(outboundLogList);
            if (save) {
            } else {
                throw new GlobalException("出库异常");
            }
//            BackDataVo backDataVo = new BackDataVo();
//            backDataVo.setMaterialCode(pickingSale.getMaterialCode());
//            backDataVo.setNetWeight(netWeight);
//            backDataVo.setSaleNumber(pickingSale.getConnectionId());
//            remoteSaleService.updateShippingWeight(backDataVo);


            //判断是否有超发
            int docHairMark = sysDocument.getDocHairMark();
            //没有超收
            if (docHairMark != 1) {

                //计划出库重量
                Double allotAmount = pickingSale1.getPlannedWeight();
                //实际出库重量
                Double allotWeightOut = pickingSale1.getActualNumber();
                if (allotWeightOut >= allotAmount) {

                    //判断是否有交接
                    int docHandoverMark = sysDocument.getDocHandoverMark();
                    //有交接
                    if (docHandoverMark == 1) {
                        //修改单据为待交接
                        pickingSale1.setWodStatus(10);
                        pickingSaleMapper.updateById(pickingSale1);

                    } else {
                        //修改单据为已完成
                        pickingSale1.setWodStatus(7);
                        //删除库存
                        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

                        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                        //拆包要修改的库存集合
                        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

                        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

                            if ("1".equals(stock.getIsPackage())) {
                                //如果是拆包的

                                //查询库存扣减数量，如果扣完数量为0则删掉库存
                                String materialNumber = stock.getPdoductNumber();
                                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                                BigDecimal subtract = wmsBig.subtract(outNumBig);
                                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                                if (flag) {
                                    deleteList.add(chaiWmsStock);
                                } else {
                                    chaiWmsStock.setWsiMaterialStatus(2);
                                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                                    updateList.add(chaiWmsStock);
                                }
                            } else {
                                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                                if (wmsStockInfo1 != null) {
                                    deleteList.add(wmsStockInfo1);
                                }

                            }
                        }

                        if (updateList.size() > 0) {
                            wmsStockInfoService.updateBatchById(updateList);
                        }

                        if (deleteList.size() > 0) {
                            wmsStockInfoMapper.deleteBatchIds(deleteList);
                        }

                        pickingSaleMapper.updateById(pickingSale1);
                    }
                }

            }
            pickingRestDbDto.setCode("200");

        } else if ("3".equals(type)) {
            //条码撤销
            PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

            if (pickingSale.getWodStatus() != 5 && pickingSale.getWodStatus() != 6) {
                throw new GlobalException("只能对待出库和出库中的单据进行条码撤销");
            }

            //在明细表中查询是否有此条码
            PickingSaleDetail pickingSaleDetail = pickingSaleDetailMapper.selectOne(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getPdoductNumber, inputValue).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
            if (pickingSaleDetail == null) {
                pickingRestDbDto.setCode("500");
                pickingRestDbDto.setMessage("撤销失败");
                return pickingRestDbDto;
            }

            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, inputValue));
            if ("1".equals(pickingSaleDetail.getIsPackage())) {
                String materialNumber = pickingSaleDetail.getPdoductNumber();
                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));

                //删除条码打印
                int delete = barCodePrintingMapper.delete(new QueryWrapper<BarCodePrint>().lambda().eq(BarCodePrint::getConnectDoc, pickingSale.getWodDocNum()).eq(BarCodePrint::getMaterialNumber, pickingSaleDetail.getPdoductNumber()));
            }


            //修改库存状态为在库

            wmsStockInfo.setWsiMaterialStatus(2);
            wmsStockInfoMapper.updateById(wmsStockInfo);


            OutboundLog outboundLog = outboundLogMapper.selectOne(new QueryWrapper<OutboundLog>().lambda().eq(OutboundLog::getWsiMaterialNumber, inputValue));

            //删除日志
            outboundLogService.removeById(outboundLog);

            //删除出库明细
            int delete = pickingSaleDetailMapper.delete(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getPdoductNumber, inputValue).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
            BigDecimal out = new BigDecimal(String.valueOf(pickingSale.getOutgoingWeight()));
            BigDecimal bigDecimal;

            bigDecimal = new BigDecimal(pickingSaleDetail.getOutgoingNumber());

            BigDecimal outWeight = out.subtract(bigDecimal);
            //修改出库重量
            pickingSale.setOutgoingWeight(outWeight.doubleValue());

            //扣除数量
            Integer outgoingNumber = pickingSale.getOutgoingNumber();
            pickingSale.setOutgoingNumber(outgoingNumber - 1);

            pickingSale.setActualNumber(outWeight.doubleValue());


            int i = pickingSaleMapper.updateById(pickingSale);
            if (i <= 0) {
                pickingRestDbDto.setMessage("撤销失败");
                pickingRestDbDto.setCode("500");
                return pickingRestDbDto;
            } else {
//                //回传销售订单发货量
//                BackDataVo backDataVo = new BackDataVo();
//                backDataVo.setMaterialCode(pickingSale.getMaterialCode());
//                backDataVo.setNetWeight(pickingSaleDetail.getNetWeight());
//                backDataVo.setSaleNumber(pickingSale.getConnectionId());
//                remoteSaleService.updateShippingWeightSub(backDataVo);
            }
            //删除品质检验单
            pickingRestDbDto.setQuantityIdentification(pickingSale.getPlannedWeight() + "/" + pickingSale.getActualNumber() + unitName);
            //出库数量
            pickingRestDbDto.setAllotNumOut(pickingSale.getOutgoingNumber() + "");

            pickingRestDbDto.setMessage("物料号码:" + inputValue + ",出库量:" + pickingSaleDetail.getOutgoingNumber() + "撤销成功");

        }

        if ("4".equals(type)) {
            //判断扫描的物料条码是否一致
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, inputValue).eq(WmsStockInfo::getWsiMaterialStatus, 2));

            if (wmsStockInfo == null) {
                pickingRestDbDto.setCode("500");
                pickingRestDbDto.setMessage("扫描失败，请核实后扫描");
                return pickingRestDbDto;
            }

            if ("1".equals(wmsStockInfo.getWsiFreezeInfo())) {
                throw new GlobalException("此物料已冻结请重新输入");
            }

            //出库数量
            String outNum = pickingRestDbVo.getOutNum();

            //扫描的物料编码
            String wsiMaterialCode = wmsStockInfo.getWsiMaterialCode();
            //查询委外发货单中的物料编码、
            PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

            if (!pickingSale.getMaterialCode().equals(wsiMaterialCode)) {
                pickingRestDbDto.setMessage("500");
                pickingRestDbDto.setMessage("扫描失败，请核实后扫描");
                return pickingRestDbDto;
            }

            //判断是否重复扫描(在明细表中查询是否有该条码)
            PickingSaleDetail pickingSaleDetail1 = pickingSaleDetailMapper.selectOne(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getPdoductNumber, inputValue).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
            if (pickingSaleDetail1 != null) {
                pickingRestDbDto.setMessage("500");
                pickingRestDbDto.setMessage("请勿重复扫描");
                return pickingRestDbDto;
            }

            if (wmsStockInfo.getWsiNetWeight()<Double.parseDouble(outNum)){
                pickingRestDbDto.setMessage("出库数量不能大于库存数量");
                pickingRestDbDto.setCode("500");
                return pickingRestDbDto;
            }

            //查询条码打印表中是否有流水号，如果没用就是001
            BarCodePrint barCodePrint1 = barCodePrintingMapper.selectOne(new QueryWrapper<BarCodePrint>().lambda().eq(BarCodePrint::getConnectDoc, pickingSale.getWodDocNum()));

            //截取物料号码前半部分
            String qz = wmsStockInfo.getWsiMaterialNumber();

            //新号码
            String newNumber = "";

            if (barCodePrint1 == null) {
                newNumber = qz + "-" + "01";
            } else {
                //获取当前的最大流水号
                String maxNumber = barCodePrintingMapper.getMaxNumber(qz);
                //当前最大流水号+1
                String manxNumber = MaxNumberUtils.getManxNumber(maxNumber);
                newNumber = qz + "-" + manxNumber;
            }

            PickingSaleDetail pickingSaleDetail = new PickingSaleDetail();
            //物料号码
            pickingSaleDetail.setPdoductNumber(newNumber);

            //物料编码
            pickingSaleDetail.setItemCode(wmsStockInfo.getWsiMaterialCode());

            //物料状态
            pickingSaleDetail.setWodStatus(3);

            //关联单号
            pickingSaleDetail.setWodDocNum(pickingSale.getWodDocNum());

            //出库数量
            pickingSaleDetail.setOutgoingNumber(outNum);

            //批次号
            pickingSaleDetail.setBatchNumber(wmsStockInfo.getWsiMaterialBatch());

            //厚度
            pickingSaleDetail.setThick(wmsStockInfo.getWsiThick());

            //幅宽
            pickingSaleDetail.setBreadth(wmsStockInfo.getWsiWidth());
            //卷长
            pickingSaleDetail.setRollLength(wmsStockInfo.getWsiLength());


            //仓储信息
            pickingSaleDetail.setWarehouseInfo(wmsStockInfo.getWsiWarehourseInfo());

            //出库人
            pickingSaleDetail.setDepositor(LoginHelper.getUsername());

            //出库时间
            pickingSaleDetail.setDeliveryTime(new Date());

            //是否拆包
            pickingSaleDetail.setIsPackage("1");

            //判断是否有检验
            int docInspectionMark = sysDocument.getDocInspectionMark();
            //如果有检验
            if (docInspectionMark == 1) {
                //修改单据明细为待检验
                pickingSaleDetail.setWodStatus(1);
            } else {
                //判断是否有交接
                int docHandoverMark = sysDocument.getDocHandoverMark();
                //有交接
                if (docHandoverMark == 1) {
                    //修改单据明细为待交接
                    pickingSaleDetail.setWodStatus(2);

                }
            }
            //添加明细
            pickingSaleDetailMapper.insert(pickingSaleDetail);

            //修改委外发货单的单据状态为出库中
            pickingSale.setWodStatus(6);
            //修改出库重量和出库数量
            Double outgoingWeight = pickingSale.getOutgoingWeight();
            if (outgoingWeight == null) {
                outgoingWeight = 0.0;
            }
            BigDecimal bigDecimal = new BigDecimal(String.valueOf(outgoingWeight));
            BigDecimal bigDecimal1 = new BigDecimal(outNum);

            BigDecimal add = bigDecimal.add(bigDecimal1);
            pickingSale.setOutgoingWeight(add.doubleValue());
            Integer outgoingNumber = pickingSale.getOutgoingNumber();
            if (outgoingNumber == null) {
                outgoingNumber = 0;
            }
            pickingSale.setOutgoingNumber(outgoingNumber + 1);


            //实际量
            pickingSale.setActualNumber(pickingSale.getOutgoingWeight());


            updateById(pickingSale);

            //修改仓库物料的状态为备料
            wmsStockInfo.setWsiMaterialStatus(5);
            int i = wmsStockInfoMapper.updateById(wmsStockInfo);


            //返回前端参数
            //计划/实际
            pickingRestDbDto.setQuantityIdentification(pickingSale.getPlannedWeight() + "/" + pickingSale.getActualNumber() + unitName);
            //出库数量
            pickingRestDbDto.setAllotNumOut(pickingSale.getOutgoingNumber() + "");

            pickingRestDbDto.setMessage("物料号码:" + inputValue + ",出库量:" + outNum + "出库成功");


            OutboundLog outboundLog = new OutboundLog();
            BeanUtils.copyProperties(wmsStockInfo, outboundLog, new String[]{"id"});
            outboundLog.setWodDocNum(pickingSale.getWodDocNum());
            outboundLog.setWsiMaterialNumber(newNumber);
            boolean save = outboundLogService.save(outboundLog);

            //生成条码打印
            BarCodePrint barCodePrint = new BarCodePrint();
            barCodePrint.setMaterialNumber(newNumber);
            barCodePrint.setPrintType("3");
            barCodePrint.setConnectDoc(pickingSale.getWodDocNum());
            barCodePrint.setMaterialCode(pickingSale.getMaterialCode());
            barCodePrint.setSupplierCode(wmsStockInfo.getWsiSupplierCode());
            barCodePrint.setNetWeight(outNum);
            barCodePrint.setCreateTime(new Date());
            barCodePrint.setCreateUser(LoginHelper.getUsername());
            barCodePrint.setDeptId(LoginHelper.getDeptId());
            barCodePrintingService.save(barCodePrint);
            //修改仓库物料的状态为备料

            //查询当前生产领料单
            PickingSale pickingSale1 = pickingSaleMapper.selectById(pickingRestDbVo.getId());
            //判断是否有超收
            int docHairMark = sysDocument.getDocHairMark();
            //没有超收
            if (docHairMark != 1) {
                //计划出库重量
                Double allotAmount = pickingSale1.getPlannedWeight();
                //实际出库重量
                Double allotWeightOut = pickingSale1.getActualNumber();
                if (allotWeightOut >= allotAmount) {

                    //判断是否有交接
                    int docHandoverMark = sysDocument.getDocHandoverMark();
                    //有交接
                    if (docHandoverMark == 1) {
                        //修改单据为待交接
                        pickingSale1.setWodStatus(10);
                        pickingSaleMapper.updateById(pickingSale1);

                    } else {
                        //修改单据为已完成
                        pickingSale1.setWodStatus(7);
                        //删除库存
                        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

                        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                        //拆包要修改的库存集合
                        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

                        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

                            if ("1".equals(stock.getIsPackage())) {
                                //如果是拆包的

                                //查询库存扣减数量，如果扣完数量为0则删掉库存
                                String materialNumber = stock.getPdoductNumber();
                                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                                BigDecimal subtract = wmsBig.subtract(outNumBig);
                                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                                if (flag) {
                                    deleteList.add(chaiWmsStock);
                                } else {
                                    chaiWmsStock.setWsiMaterialStatus(2);
                                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                                    updateList.add(chaiWmsStock);
                                }
                            } else {
                                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                                if (wmsStockInfo1 != null) {
                                    deleteList.add(wmsStockInfo1);
                                }

                            }
                        }

                        if (updateList.size() > 0) {
                            wmsStockInfoService.updateBatchById(updateList);
                        }

                        if (deleteList.size() > 0) {
                            wmsStockInfoMapper.deleteBatchIds(deleteList);
                        }

                        pickingSaleMapper.updateById(pickingSale1);
                    }
                }

            }
            //拣货方案
            SchemeDto point = point(pickingRestDbVo.getId());

            if (point.getCombinationName() != null) {
                pickingRestDbDto.setPickingPrompt(point.getCombinationName());
            }

            pickingRestDbDto.setCode("200");
        }


        pickingRestDbDto.setCode("200");
        SchemeDto point = point(pickingRestDbVo.getId());
        pickingRestDbDto.setPickingPrompt(point.getCombinationName());
        return pickingRestDbDto;
    }

    /**
     * 销售发货列表（不分页）
     *
     * @param pickingSaleVo
     * @return
     */
    @Override
    public List<PickingSaleDto> noPageList(PickingSaleVo pickingSaleVo) {
        return pickingSaleMapper.getNoPageList(pickingSaleVo);
    }

    /**
     * 拣货完成
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean finishProduction(Long id) {
        //判断当前页面是否有配置送检和交接，如果有则生成品检单

        //获取菜单id
        Long menuId = remoteMenuService.getIdByMenuName("销售发货");
        SysDocumentResultDto sysDocument = remoteDocumentService.getInfoConfig(menuId);

        //查出销售发货信息单
        PickingSale pickingSale = pickingSaleMapper.selectById(id);


        //判断是否有交接
        int docHandoverMark = sysDocument.getDocHandoverMark();
        //有交接
        if (docHandoverMark == 1) {
            //修改单据状态为待交接
            pickingSale.setWodStatus(10);
            return pickingSaleMapper.updateById(pickingSale) > 0;
        }

        //修改单据状态为已完成
        pickingSale.setWodStatus(7);

        //删除库存
        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

        //拆包要修改的库存集合
        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

            if ("1".equals(stock.getIsPackage())) {
                //如果是拆包的

                //查询库存扣减数量，如果扣完数量为0则删掉库存
                String materialNumber = stock.getPdoductNumber();
                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                BigDecimal subtract = wmsBig.subtract(outNumBig);
                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                if (flag) {
                    deleteList.add(chaiWmsStock);
                } else {
                    chaiWmsStock.setWsiMaterialStatus(2);
                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                    updateList.add(chaiWmsStock);
                }
            } else {
                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                if (wmsStockInfo1 != null) {
                    deleteList.add(wmsStockInfo1);
                }
            }
        }

        if (updateList.size() > 0) {
            wmsStockInfoService.updateBatchById(updateList);
        }

        if (deleteList.size() > 0) {
            wmsStockInfoMapper.deleteBatchIds(deleteList);
        }


        return pickingSaleMapper.updateById(pickingSale) > 0;
    }

    /**
     * 拣货撤销
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean repealProduction(Long id) {
        //修改单据状态为待出库
        PickingSale pickingSale = pickingSaleMapper.selectById(id);
        pickingSale.setWodStatus(5);
        //实际重量，出库重量，出库数量清空
        pickingSale.setActualNumber(0.0);
        pickingSale.setOutgoingNumber(0);
        pickingSale.setOutgoingWeight(0.0);
        //交接数量，交接重量清空
        pickingSale.setOverWeight(0.0);
        pickingSale.setOverNum(0);
        pickingSaleMapper.updateById(pickingSale);

        //查询明细
        List<PickingSaleDetail> pickingSaleDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

        //日志表集合
        List<OutboundLog> outboundLogList = outboundLogMapper.selectList(new QueryWrapper<OutboundLog>().lambda().eq(OutboundLog::getWodDocNum, pickingSale.getWodDocNum()));

//        List<WmsStockInfo> wmsStockInfoList = new ArrayList<>();
        //遍历
        for (PickingSaleDetail pickingSaleDetail : pickingSaleDetailList) {
            //将仓库中的物料全修改为在库
            //修改仓库状态为在库
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, pickingSaleDetail.getPdoductNumber()));
            wmsStockInfo.setWsiMaterialStatus(2);

            //如果是拆包
            if ("1".equals(pickingSaleDetail.getIsPackage())) {
                String materialNumber = pickingSaleDetail.getPdoductNumber();

                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));

                WmsStockInfo chaiWms = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                chaiWms.setWsiMaterialStatus(2);
                wmsStockInfoService.updateById(chaiWms);
//                wmsStockInfoList.add(chaiWms);
            } else {
                wmsStockInfoService.updateById(wmsStockInfo);
            }
//            //修改库存状态
//            wmsStockInfoService.updateBatchById(wmsStockInfoList);

            //删除条码打印
            int delete = barCodePrintingMapper.delete(new QueryWrapper<BarCodePrint>().lambda().eq(BarCodePrint::getConnectDoc, pickingSale.getWodDocNum()));
        }
        //删除日志表中的数据
        outboundLogService.removeBatchByIds(outboundLogList);

        //删除所有明细
        int i = pickingSaleDetailMapper.delete(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

        return i > 0;
    }


    /**
     * 交接
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickingRestHandoverDto overProduction(PickingRestDbVo pickingRestDbVo) {
        //获取步骤
        int step = pickingRestDbVo.getExecutionOrder();
        //获取输入值
        String inputValue = pickingRestDbVo.getInputValue();
        //返回值
        PickingRestHandoverDto pickingRestHandoverDto = new PickingRestHandoverDto();
        //获取菜单id
        Long menuId = remoteMenuService.getIdByMenuName("销售发货");
        SysDocumentResultDto sysDocument = remoteDocumentService.getInfoConfig(menuId);
        //拿到交接方式
        int jjType = Integer.parseInt(sysDocument.getDocHandoverMethod());

        if (step == 1) {

            //校验员工编号
            R<SysUser> byUserName = remoteUserService.getByUserName(pickingRestDbVo.getInputValue());
            SysUser userInfo = byUserName.getData();

            if (userInfo == null) {
                pickingRestHandoverDto.setResultCode("500");
                pickingRestHandoverDto.setMessage("交接人输入有误,请核对后输入");
                return pickingRestHandoverDto;
            }

            //返回交接人
            pickingRestHandoverDto.setHandoverName(userInfo.getUserName() + "-" + userInfo.getNickName());
            pickingRestHandoverDto.setDocHandoverMethod(jjType);


            if (jjType == 1) {
                pickingRestHandoverDto.setMessage("请输入物料条码");
            } else if (jjType == 2) {
                pickingRestHandoverDto.setMessage("请输入批次号");
            } else if (jjType == 3) {
                PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

                pickingRestDbVo.setInputValue(pickingSale.getWodDocNum());

                //查询物料单位
                String unitName = remoteUnitService.getUnitDataByCode(pickingSale.getMaterialUnit()).getData().getUnitName();

                //判断是否存在明细表中
                List<PickingSaleDetail> pickingSaleDetailList1 = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingRestDbVo.getInputValue()));
                if (pickingSaleDetailList1 == null) {
                    pickingRestHandoverDto.setResultCode("500");
                    pickingRestHandoverDto.setMessage("交接失败");
                    return pickingRestHandoverDto;
                }

                //查询当前单据号在明细中是否存在，且状态为待交接
                List<PickingSaleDetail> pickingSaleDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingRestDbVo.getInputValue()).eq(PickingSaleDetail::getWodStatus, 2));
                if (pickingSaleDetailList.size() == 0) {
                    pickingRestHandoverDto.setMessage("交接失败,请核实后再录入");
                    pickingRestHandoverDto.setResultCode("500");
                    return pickingRestHandoverDto;
                } else {
                    //查出当前为待交接状态的单据明细,算出总净重和总数量
                    Double sumPiHao = pickingSaleDetailMapper.getDoc(pickingRestDbVo.getInputValue());
                    //总数量
                    long sumNum = pickingSaleDetailList.size();

                    //出库重量
                    Double allotAmount = pickingSale.getOutgoingWeight();

                    //返回计划/实际

                    //(实际交接)
                    Double overWeight = pickingSale.getOverWeight();
                    if (overWeight == null) {
                        overWeight = 0.0;
                    }
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(overWeight));
                    //查询号码在明细中的重量
                    BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(sumPiHao));
                    BigDecimal add = bigDecimal.add(bigDecimal1);

                    pickingSale.setOverWeight(add.doubleValue());

                    pickingRestHandoverDto.setQuantityIdentification(allotAmount + "/" + add.toString() + unitName);


                    //保存交接数量，交接重量
                    Integer overNum = pickingSale.getOverNum();
                    if (overNum == null) {
                        overNum = 0;
                    }
                    int jjSum = (int) sumNum;
                    pickingSale.setOverNum(overNum + jjSum);

                    //取出关节人
                    String closeUser = pickingSale.getCloseMan();
                    if (closeUser == null) {
                        closeUser = "";
                    }
                    String[] split = closeUser.split(",");

                    //获取交接人名称
                    String name = LoginHelper.getUsername();

                    //定义变量记录交接人是否相等
                    int jj = 0;

                    if (closeUser != null && !"".equals(closeUser)) {
                        for (String s : split) {
                            if (!name.equals(s)) {
                                jj = 1;
                            }
                        }
                    } else {
                        pickingSale.setCloseMan(name);
                    }


                    if (jj == 1) {
                        pickingSale.setCloseMan("," + name);
                    }
                    pickingSale.setCloseTime(new Date());

                    //出库/交接
                    pickingRestHandoverDto.setOutHandoverActual(pickingSale.getOutgoingNumber() + "/" + pickingSale.getOverNum());

                    for (PickingSaleDetail pickingSaleDetail : pickingSaleDetailList) {
                        //修改物料状态明细为已出库
                        pickingSaleDetail.setWodStatus(3);
                        pickingSaleDetailMapper.updateById(pickingSaleDetail);
                    }


                    //判断是否所有物料没有待交接的状态
                    List<PickingSaleDetail> pickingSaleDetailList2 = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodStatus, 2).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                    if (pickingSaleDetailList2.size() == 0) {
                        //修改单据状态为已完成
                        pickingSale.setWodStatus(7);
                        //删除库存
                        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

                        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                        //拆包要修改的库存集合
                        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

                        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

                            if ("1".equals(stock.getIsPackage())) {
                                //如果是拆包的

                                //查询库存扣减数量，如果扣完数量为0则删掉库存
                                String materialNumber = stock.getPdoductNumber();
                                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                                BigDecimal subtract = wmsBig.subtract(outNumBig);
                                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                                if (flag) {
                                    deleteList.add(chaiWmsStock);
                                } else {
                                    chaiWmsStock.setWsiMaterialStatus(2);
                                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                                    updateList.add(chaiWmsStock);
                                }
                            } else {
                                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                                if (wmsStockInfo1 != null) {
                                    deleteList.add(wmsStockInfo1);
                                }
                            }
                        }
                        if (updateList.size() > 0) {
                            wmsStockInfoService.updateBatchById(updateList);
                        }

                        if (deleteList.size() > 0) {
                            wmsStockInfoMapper.deleteBatchIds(deleteList);
                        }

                    }
                    boolean b = updateById(pickingSale);
                    if (!b) {
                        pickingRestHandoverDto.setResultCode("500");
                        pickingRestHandoverDto.setMessage("交接失败");
                        return pickingRestHandoverDto;
                    }

                    //消息提示
                    pickingRestHandoverDto.setMessage("单据号:" + pickingRestDbVo.getInputValue() + ",数量:" + sumNum + ",交接成功");
                }
            }
            pickingRestHandoverDto.setResultCode("200");
            return pickingRestHandoverDto;

        } else if (step == 2) {
            //如果是单个物料交接
            if (jjType == 1) {
                //查询当前的出库单信息
                PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

                //查询物料单位
                String unitName = remoteUnitService.getUnitDataByCode(pickingSale.getMaterialUnit()).getData().getUnitName();


                //查询出库明细
                PickingSaleDetail pickingSaleDetail = pickingSaleDetailMapper.selectOne(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getPdoductNumber, inputValue).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
                if (pickingSaleDetail == null) {
                    pickingRestHandoverDto.setResultCode("500");
                    pickingRestHandoverDto.setMessage("交接失败");
                    return pickingRestHandoverDto;
                }

                //判断当前物料是否属于待交接
                if (pickingSaleDetail.getWodStatus() != 2) {
                    pickingRestHandoverDto.setResultCode("500");
                    pickingRestHandoverDto.setMessage("不可重复交接");
                    return pickingRestHandoverDto;
                } else {
                    //出库重量
                    Double allotAmount = pickingSale.getOutgoingWeight();

                    Double overWeight = pickingSale.getOverWeight();
                    if (overWeight == null) {
                        overWeight = 0.0;
                    }
                    //(实际交接)
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(overWeight));
                    //查询号码在明细中的重量
                    BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(pickingSaleDetail.getOutgoingNumber()));
                    BigDecimal add = bigDecimal.add(bigDecimal1);

                    pickingSale.setOverWeight(add.doubleValue());

                    pickingRestHandoverDto.setQuantityIdentification(allotAmount + "/" + add.toString() + unitName);


                    //保存交接数量，交接重量
                    Integer overNum = pickingSale.getOverNum();
                    if (overNum == null) {
                        overNum = 0;
                    }
                    pickingSale.setOverNum(overNum + 1);

                    //取出关节人
                    String closeUser = pickingSale.getCloseMan();
                    if (closeUser == null) {
                        closeUser = "";
                    }
                    String[] split = closeUser.split(",");

                    //获取交接人名称
                    String name = LoginHelper.getUsername();

                    //定义变量记录交接人是否相等
                    int jj = 0;

                    if (closeUser != null && !"".equals(closeUser)) {
                        for (String s : split) {
                            if (!name.equals(s)) {
                                jj = 1;
                            }
                        }
                    } else {
                        pickingSale.setCloseMan(name);
                    }


                    if (jj == 1) {
                        pickingSale.setCloseMan("," + name);
                    }
                    pickingSale.setCloseTime(new Date());
                    //出库/交接
                    pickingRestHandoverDto.setOutHandoverActual(pickingSale.getOutgoingNumber() + "/" + pickingSale.getOverNum());

                    //修改物料状态明细为已出库
                    pickingSaleDetail.setWodStatus(3);
                    pickingSaleDetailMapper.updateById(pickingSaleDetail);


                    //判断是否所有物料没有待交接的状态
                    List<PickingSaleDetail> pickingSaleDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodStatus, 2).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
                    if (pickingSaleDetailList.size() == 0) {
                        //修改单据状态为已完成
                        pickingSale.setWodStatus(7);
                        //删除库存
                        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

                        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                        //拆包要修改的库存集合
                        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

                        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

                            if ("1".equals(stock.getIsPackage())) {
                                //如果是拆包的

                                //查询库存扣减数量，如果扣完数量为0则删掉库存
                                String materialNumber = stock.getPdoductNumber();
                                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                                BigDecimal subtract = wmsBig.subtract(outNumBig);
                                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                                if (flag) {
                                    deleteList.add(chaiWmsStock);
                                } else {
                                    chaiWmsStock.setWsiMaterialStatus(2);
                                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                                    updateList.add(chaiWmsStock);
                                }
                            } else {
                                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                                if (wmsStockInfo1 != null) {
                                    deleteList.add(wmsStockInfo1);
                                }

                            }
                        }
                        if (updateList.size() > 0) {
                            wmsStockInfoService.updateBatchById(updateList);
                        }

                        if (deleteList.size() > 0) {
                            wmsStockInfoMapper.deleteBatchIds(deleteList);
                        }

                    }

                    boolean b = updateById(pickingSale);
                    if (!b) {
                        pickingRestHandoverDto.setResultCode("500");
                        pickingRestHandoverDto.setMessage("交接失败");
                        return pickingRestHandoverDto;
                    }

                    //消息提示
                    pickingRestHandoverDto.setMessage("物料号码:" + pickingRestDbVo.getInputValue() + ",净含量" + pickingSaleDetail.getOutgoingNumber() + "数量:" + 1 + ",交接成功");

                }
            } else if (jjType == 2) {
                PickingSale pickingSale = pickingSaleMapper.selectById(pickingRestDbVo.getId());

                //查询物料单位
                String unitName = remoteUnitService.getUnitDataByCode(pickingSale.getMaterialUnit()).getData().getUnitName();
                //判断是否存在明细表中
                List<PickingSaleDetail> pickingSaleDetailList1 = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getBatchNumber, pickingRestDbVo.getInputValue()).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
                if (pickingSaleDetailList1 == null) {
                    pickingRestHandoverDto.setMessage("交接失败,请核实后再录入");
                    pickingRestHandoverDto.setResultCode("500");
                    return pickingRestHandoverDto;
                }

                //查询当前批号在明细中是否存在，且状态为待交接
                List<PickingSaleDetail> pickingSaleDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getBatchNumber, pickingRestDbVo.getInputValue()).eq(PickingSaleDetail::getWodStatus, 2).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));
                if (pickingSaleDetailList.size() == 0) {
                    pickingRestHandoverDto.setMessage("不可重复交接");
                    pickingRestHandoverDto.setResultCode("500");
                    return pickingRestHandoverDto;
                } else {
                    //查出当前为待交接状态的批次，算出总净重和总数量
                    Double sumPiHao = pickingSaleDetailMapper.getPiHao(pickingRestDbVo.getInputValue());
                    //总数量
                    long sumNum = pickingSaleDetailList.size();

                    //出库重量
                    Double allotAmount = pickingSale.getOutgoingWeight();

                    //返回计划/实际

                    //(实际交接)
                    Double overWeight = pickingSale.getOverWeight();
                    if (overWeight == null) {
                        overWeight = 0.0;
                    }
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(overWeight));
                    //查询号码在明细中的重量
                    BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(sumPiHao));
                    BigDecimal add = bigDecimal.add(bigDecimal1);

                    pickingSale.setOverWeight(add.doubleValue());

                    pickingRestHandoverDto.setQuantityIdentification(allotAmount + "/" + add.toString() + unitName);


                    //保存交接数量，交接重量
                    Integer overNum = pickingSale.getOverNum();
                    if (overNum == null) {
                        overNum = 0;
                    }
                    int jjSum = (int) sumNum;
                    pickingSale.setOverNum(overNum + jjSum);

                    //取出关节人
                    String closeUser = pickingSale.getCloseMan();
                    if (closeUser == null) {
                        closeUser = "";
                    }
                    String[] split = closeUser.split(",");

                    //获取交接人名称
                    String name = LoginHelper.getUsername();

                    //定义变量记录交接人是否相等
                    int jj = 0;

                    if (closeUser != null && !"".equals(closeUser)) {
                        for (String s : split) {
                            if (!name.equals(s)) {
                                jj = 1;
                            }
                        }
                    } else {
                        pickingSale.setCloseMan(name);
                    }


                    if (jj == 1) {
                        pickingSale.setCloseMan("," + name);
                    }
                    pickingSale.setCloseTime(new Date());


                    //出库/交接
                    pickingRestHandoverDto.setOutHandoverActual(pickingSale.getOutgoingNumber() + "/" + pickingSale.getOverNum());

                    for (PickingSaleDetail pickingSaleDetail : pickingSaleDetailList) {
                        //修改物料状态明细为已出库
                        pickingSaleDetail.setWodStatus(3);
                        pickingSaleDetailMapper.updateById(pickingSaleDetail);
                    }


                    //判断是否所有物料没有待交接的状态
                    List<PickingSaleDetail> pickingSaleDetailList2 = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodStatus, 2).eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                    if (pickingSaleDetailList2.size() == 0) {
                        //修改单据状态为已完成
                        pickingSale.setWodStatus(7);

                        //删除库存
                        List<WmsStockInfo> deleteList = new ArrayList<WmsStockInfo>();

                        List<PickingSaleDetail> pickingOutsourceDetailList = pickingSaleDetailMapper.selectList(new QueryWrapper<PickingSaleDetail>().lambda().eq(PickingSaleDetail::getWodDocNum, pickingSale.getWodDocNum()));

                        //拆包要修改的库存集合
                        List<WmsStockInfo> updateList = new ArrayList<WmsStockInfo>();

                        for (PickingSaleDetail stock : pickingOutsourceDetailList) {

                            if ("1".equals(stock.getIsPackage())) {
                                //如果是拆包的

                                //查询库存扣减数量，如果扣完数量为0则删掉库存
                                String materialNumber = stock.getPdoductNumber();
                                String number = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
                                WmsStockInfo chaiWmsStock = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, number));
                                BigDecimal wmsBig = new BigDecimal(String.valueOf(chaiWmsStock.getWsiNetWeight()));
                                BigDecimal outNumBig = new BigDecimal(stock.getOutgoingNumber());
                                BigDecimal subtract = wmsBig.subtract(outNumBig);
                                boolean flag = subtract.compareTo(BigDecimal.ZERO) == 0;
                                if (flag) {
                                    deleteList.add(chaiWmsStock);
                                } else {
                                    chaiWmsStock.setWsiMaterialStatus(2);
                                    chaiWmsStock.setWsiNetWeight(subtract.doubleValue());
                                    updateList.add(chaiWmsStock);
                                }
                            } else {
                                WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, stock.getPdoductNumber()));
                                if (wmsStockInfo1 != null) {
                                    deleteList.add(wmsStockInfo1);
                                }

                            }
                        }

                        if (updateList.size() > 0) {
                            wmsStockInfoService.updateBatchById(updateList);
                        }

                        if (deleteList.size() > 0) {
                            wmsStockInfoMapper.deleteBatchIds(deleteList);
                        }

                    }
                    boolean b = updateById(pickingSale);
                    if (!b) {
                        pickingRestHandoverDto.setMessage("交接失败");
                        pickingRestHandoverDto.setResultCode("500");
                        return pickingRestHandoverDto;
                    }

                    //消息提示
                    pickingRestHandoverDto.setMessage("批次号:" + pickingRestDbVo.getInputValue() + ",数量:" + sumNum + ",交接成功");
                }
            } else if (jjType == 3) {
                pickingRestHandoverDto.setResultCode("500");
                pickingRestHandoverDto.setMessage("请勿重复交接");

            }
        }
        pickingRestHandoverDto.setResultCode("200");
        return pickingRestHandoverDto;
    }

    /**
     * 根据单据类型查询列表(销售发票)
     *
     * @param saleInvoiceVo
     * @return
     */
    @Override
    public TableDataInfo<SaleInvoiceDto> getSaleInvoice(SaleInvoiceVo saleInvoiceVo, PageQuery pageQuery) {
        int type = saleInvoiceVo.getType();
        //定义表名
        String tableName = "";
        if (type == 1) {
            //如果type=1，则是销售发货
            tableName = "picking_sale";
        } else if (type == 2) {
            tableName = "picking_purchase";
        } else {
            tableName = "picking_rest";
        }
        Page<SaleInvoiceDto> list = pickingSaleMapper.getSaleInvoice(pageQuery.build(), tableName, saleInvoiceVo);
        for (SaleInvoiceDto saleInvoiceDto : list.getRecords()) {
            //根据type添加单据类型
            if (type == 1) {
                saleInvoiceDto.setDocumentType("销售发货");
            } else if (type == 2) {
                saleInvoiceDto.setDocumentType("采购退货");
            } else {
                saleInvoiceDto.setDocumentType("其他出库");
            }
            //查询辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + saleInvoiceDto.getTenantId(), String.valueOf(saleInvoiceDto.getMaterialId()));
            saleInvoiceDto.setAuxiliaryAttribute(statsArray);
        }
        return TableDataInfo.build(list);
    }

    /**
     * 销售发票新增单据列表
     *
     * @param saleInvoiceVo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<SaleInvoiceDto> saleInvoicedList(SaleInvoiceVo saleInvoiceVo, PageQuery pageQuery) {
        Page<SaleInvoiceDto> list = pickingSaleMapper.getSaleInvoice(pageQuery.build(), "picking_sale", saleInvoiceVo);
        for (SaleInvoiceDto saleInvoiceDto : list.getRecords()) {
            //查询辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + saleInvoiceDto.getTenantId(), String.valueOf(saleInvoiceDto.getMaterialId()));
            saleInvoiceDto.setAuxiliaryAttribute(statsArray);

            SaleServiceVo saleServiceVo = new SaleServiceVo();
            saleServiceVo.setSalesOrderNum(saleInvoiceDto.getConnectionId());
            saleServiceVo.setMaterialCode(saleInvoiceDto.getMaterialCode());
            //查询单价
            String unitPrice = saleInvoiceDto.getUnitPrice();
            if (unitPrice == null) {
                unitPrice = "0";
            }

            //开票数量
            String invoicedQuantity = saleInvoiceDto.getInvoicedQuantity();
            if (invoicedQuantity == null) {
                invoicedQuantity = "0";
            }

            //未开票数量
            BigDecimal planNumBig = new BigDecimal(saleInvoiceDto.getPlanNum());//计划数量
            BigDecimal InvoiceNumBig = new BigDecimal(invoicedQuantity);//开票数量
            BigDecimal notInvoiceNumBig = planNumBig.subtract(InvoiceNumBig);//未开票数量

            BigDecimal notInvoicePlaceBig = notInvoiceNumBig.multiply(new BigDecimal(unitPrice));//未开票金额

            BigDecimal InvoicePlaceBig = InvoiceNumBig.multiply(new BigDecimal(unitPrice));//开票金额

            saleInvoiceDto.setNotInvoicedQuantity(notInvoiceNumBig.toString());
            saleInvoiceDto.setNotInvoicedPlace(notInvoicePlaceBig.toString());
            saleInvoiceDto.setInvoicedPlace(InvoicePlaceBig.toString());

            saleInvoiceDto.setDocumentType("销售发货");

            //单位
            String unitName = remoteUnitService.getUnitDataByCode(saleInvoiceDto.getMaterialUnit()).getData().getUnitName();
            saleInvoiceDto.setMaterialUnitDict(unitName);
        }
        return TableDataInfo.build(list);
    }

    /**
     * 查询收款单和付款单需要的销售发货,销售退货和采购退货，采购入库列表
     */
    @Override
    public TableDataInfo<ReceiptAndPaymentDocDto> getReceiptAndPaymentDoc(ReceiptAndPaymentDocVo saleServiceVo, PageQuery pageQuery) {

        Page<ReceiptAndPaymentDocDto> list = new Page<>();
        if ("1".equals(saleServiceVo.getType())) {
            //收款单
            list = pickingSaleMapper.getReceiptAndPaymentDoc(pageQuery.build(), saleServiceVo);
        } else if ("2".equals(saleServiceVo.getType())) {
            //付钱款单
            list = pickingSaleMapper.payment(pageQuery.build(), saleServiceVo);
        }


        for (ReceiptAndPaymentDocDto record : list.getRecords()) {
            //算出核销总金额
            BigDecimal planBig = new BigDecimal(record.getPlannedWeight());//计划数量

            //如果单价未空给0
            String unitPrice = record.getUnitPrice();
            if (unitPrice == null) {
                unitPrice = "0";
            }

            BigDecimal bigDecimal = new BigDecimal(unitPrice); //单价

            BigDecimal sumMoney = bigDecimal.multiply(planBig);//总金额

            //核销金额
            String approvedAmount = record.getApprovedAmount();
            if (record.getApprovedAmount() == null) {
                approvedAmount = "0";
                record.setApprovedAmount("0");
            }

            //算出未核销金额
            BigDecimal subtract = sumMoney.subtract(new BigDecimal(approvedAmount));

            //核销总金额
            if ("10".equals(record.getDocumentType()) || "9".equals(record.getDocumentType())) {
                record.setDocumentAmount("-" + sumMoney);
            } else {
                record.setDocumentAmount(sumMoney.toString());
            }

            //未核销金额
            record.setNotApprovedAmount(subtract.toString());

            record.setDocumentType(DocumentTypeEnum.getValue(Integer.parseInt(record.getDocumentType())));

        }
        return TableDataInfo.build(list);
    }

    /**
     * 修改发票数量和核单金额
     *
     * @param list
     * @return
     */
    @Override
    public boolean updateStorage(List<InvoiceVo> list) {

        for (InvoiceVo invoiceVo : list) {

            //销售发票（修改开票数量）
            if (invoiceVo.getType() == 1) {
                //如果发票数量不为空
                if (invoiceVo.getInvoicedQuantity() != null) {

                    //累加发票数量
                    BigDecimal bigDecimal = new BigDecimal(invoiceVo.getInvoicedQuantity());

                    //查询当前发票的数量
                    PickingSale pickingSale = pickingSaleMapper.selectOne(new QueryWrapper<PickingSale>().lambda().eq(PickingSale::getWodDocNum, invoiceVo.getWodDocNum()));
                    BigDecimal bigDecimal1 = new BigDecimal(pickingSale.getInvoicedQuantity());
                    String invoiceQuantity = bigDecimal1.add(bigDecimal).toString();

                    boolean updateQuantity = pickingSaleMapper.updateInvoicedQuatity("picking_sale", invoiceQuantity, invoiceVo.getWodDocNum());
                }
            } else if (invoiceVo.getType() == 2) {
                //如果核单金额不为空
                if (invoiceVo.getApprovedAmount() != null) {

                    //表名
                    String tableName = "";

                    //累加核单金额
                    BigDecimal bigDecimal = new BigDecimal(invoiceVo.getApprovedAmount());

                    //单据类型
                    String documentType = invoiceVo.getDocumentType();

                    String approvedAmount = "";

                    if ("销售发货".equals(documentType)) {
                        //查询当前发票的数量
                        PickingSale pickingSale = pickingSaleMapper.selectOne(new QueryWrapper<PickingSale>().lambda().eq(PickingSale::getWodDocNum, invoiceVo.getWodDocNum()));
                        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(pickingSale.getApprovedAmount()));
                        approvedAmount = bigDecimal1.add(bigDecimal).toString();
                        tableName = "picking_sale";
                    }

                    if ("采购退货".equals(documentType)) {
                        //查询当前发票的数量
                        PickingPurchase pickingPurchase = pickingPurchaseMapper.selectOne(new QueryWrapper<PickingPurchase>().lambda().eq(PickingPurchase::getWodDocNum, invoiceVo.getWodDocNum()));
                        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(pickingPurchase.getApprovedAmount()));
                        approvedAmount = bigDecimal1.add(bigDecimal).toString();
                        tableName = "picking_purchase";
                    }

                    if ("采购入库".equals(documentType)) {
                        //查询当前发票的数量
                        PurchaseReceipt purchaseReceipt = purchaseReceiptMapper.selectOne(new QueryWrapper<PurchaseReceipt>().lambda().eq(PurchaseReceipt::getReceiptNo, invoiceVo.getWodDocNum()));
                        BigDecimal bigDecimal1 = purchaseReceipt.getApprovedAmount();
                        purchaseReceipt.setApprovedAmount(bigDecimal1.add(bigDecimal));
                        purchaseReceiptMapper.updateById(purchaseReceipt);
                    }

                    if ("销售退货".equals(documentType)) {
                        //查询当前发票的数量
                        SalesReturn salesReturn = salesReturnMapper.selectOne(new QueryWrapper<SalesReturn>().lambda().eq(SalesReturn::getReceiptNo, invoiceVo.getWodDocNum()));
                        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(salesReturn.getApprovedAmount()));
                        salesReturn.setApprovedAmount(bigDecimal1.add(bigDecimal).doubleValue());
                        salesReturnMapper.updateById(salesReturn);
                    }
                    if (!"".equals(tableName)) {
                        boolean updateApprovedAmount = pickingSaleMapper.updateApprovedAmount(tableName, approvedAmount, invoiceVo.getWodDocNum());
                    }

                }

            }
        }

        return list.size() > 0;
    }

    /**
     * 通过客户编码获取总欠款数
     *
     * @param customerCode
     * @return
     */
    @Override
    public String getBalance(String customerCode) {

        List<PickingSale> pickingSales = pickingSaleMapper.selectList(new QueryWrapper<PickingSale>().lambda()
            .eq(PickingSale::getCustomerNum, customerCode));
        BigDecimal bigDecimal = new BigDecimal("0");
        BigDecimal bigDecimal1 = new BigDecimal("0");
        if (pickingSales.size() > 0) {
            for (PickingSale entity : pickingSales) {
                if (entity.getUnitPrice() != null) {
                    //单价
                    String unitPrice = entity.getUnitPrice();
                    //数量
                    String s = String.valueOf(entity.getPlannedWeight());
                    BigDecimal multiply = new BigDecimal(unitPrice).multiply(new BigDecimal(s));
                    bigDecimal = bigDecimal.add(multiply);
                }
                if (entity.getApprovedAmount() != null) {
                    bigDecimal1 = bigDecimal1.add(new BigDecimal(String.valueOf(entity.getApprovedAmount())));
                }
            }
            return bigDecimal.subtract(bigDecimal1).toString();
        }
        return bigDecimal.toString();
    }

    /**
     * 财务-核销单 通过客户编码获取销售发货数据
     *
     * @param getDataByCodeVo
     * @return
     */
    @Override
    public TableDataInfo<ImparityDto> getDataByCode(GetDataByCodeVo getDataByCodeVo, PageQuery pageQuery) {
        //根据客户编码获取销售发货数据
        Page<ImparityDto> imparityDtos = pickingSaleMapper.selectDataBySupplierCode(getDataByCodeVo, pageQuery.build());
        List<ImparityDto> records = imparityDtos.getRecords();
        if (records.size() > 0) {
            for (ImparityDto entity : records) {
                //单据类型
                entity.setReceiptType(DocumentTypeEnum.getValue(Integer.parseInt(entity.getReceiptType())));
                //单据金额
                BigDecimal multiply = new BigDecimal(String.valueOf(entity.getUnitPrice())).multiply(new BigDecimal(String.valueOf(entity.getPlannedWeight())));
                entity.setDocumentAmount(multiply.toString());
                //已核销金额
                entity.setApprovedAmount(entity.getApprovedAmount());
                //未核销金额
                if (entity.getApprovedAmount() == null) {
                    entity.setNotApprovedAmount(multiply.toString());
                } else {
                    BigDecimal subtract = multiply.subtract(new BigDecimal(entity.getApprovedAmount()));
                    entity.setNotApprovedAmount(subtract.toString());
                }
            }
            return TableDataInfo.build(imparityDtos);
        }
        return null;
    }
}
